package com.ldoublem.loadingviewlib;



import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Arc;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PathEffect;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.render.Texture;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.media.image.PixelMap;
import ohos.media.image.common.Size;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import static ohos.agp.animation.Animator.CurveType.LINEAR;
import static ohos.media.image.common.PixelFormat.ARGB_8888;

public class LVSunSetView extends Component implements Component.EstimateSizeListener, Component.DrawTask{
    private HMEventHandler hmEventHandler;

    public LVSunSetView(Context context) {
        super(context);
        initPaint();
    }

    public LVSunSetView(Context context, AttrSet attrs) {
        super(context, attrs);
        initPaint();
    }

    public LVSunSetView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
    }


    int sun_angle = 12;
    String SunstartTime = "2019-09-06 05:38:00";
    String SunendTime = "2019-09-06 18:16:00";


    public void setSunstartTime(String sunstartTime) {
        SunstartTime = sunstartTime;
        invalidate();
    }

    public void setSunendTime(String sunendTime) {
        SunendTime = sunendTime;
        invalidate();
    }



    Paint mPaint;


    public void startSunset() {
        int eventId = 0;
        long param = 1;
        Object object = null;
        InnerEvent event = InnerEvent.get(eventId, param, object);
        hmEventHandler.sendEvent(event, 200, EventHandler.Priority.IMMEDIATE);

    }


    public void start() {
        stopAnim();
        float intervalf = 0f;
        try {
            long TodayInterval = getTimeInterval(SunstartTime, SunendTime);
            Timestamp ts = new Timestamp(System.currentTimeMillis());
            String nowtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ts.getTime());
            long nowInterval = getTimeInterval(SunstartTime, nowtime);
            intervalf = nowInterval * 1.0f / TodayInterval;
            if (intervalf > 1f) {
                intervalf = 1f;
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }


        startViewAnim(0f, 1f, (long) (4000 * intervalf));

    }


    private void initPaint() {
        addDrawTask(this);
        setEstimateSizeListener(this);
        hmEventHandler = new HMEventHandler(EventRunner.current());
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mPaint.setColor(Color.WHITE);
        mPaint.setStrokeWidth(4);

    }

    int mWidth = 0;
    int mHeight = 0;




    private AnimatorValue valueAnimator = new AnimatorValue();
    private float mAnimatedValue = 0f;

    public void stopAnim() {
        if (valueAnimator != null) {
            createAnimatorProperty().reset();
            valueAnimator.setLoopedCount(0);
            valueAnimator.cancel();
            mAnimatedValue = 0f;
            invalidate();
        }
    }

    private AnimatorValue startViewAnim(float startF, final float endF, long time) {

        valueAnimator.setDuration(time);
        valueAnimator.setCurveType(LINEAR);
        valueAnimator.setLoopedCount(0);

        valueAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                mAnimatedValue = v;

                invalidate();
            }
        });

        if(!valueAnimator.isRunning()) {
            valueAnimator.start();

        }

        return valueAnimator;
    }


    public long getTimeInterval(String oldTime, String newTime) throws ParseException {

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long NTime = df.parse(newTime).getTime();
        long OTime = df.parse(oldTime).getTime();
        long diff = (NTime - OTime) / 1000 / 60;
        return diff;
    }


    private String getTimeText(String tsStr) {
        Timestamp ts = new Timestamp(System.currentTimeMillis());
        String time = "00:00";
        try {
            ts = Timestamp.valueOf(tsStr);
            time = new SimpleDateFormat("HH:mm").format(ts.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return time;
    }

    private PixelMap getSunbg(float intervalf) {
        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(mWidth, mHeight - mWidth / 6);
        initializationOptions.pixelFormat = ARGB_8888;
        PixelMap b = PixelMap.create(initializationOptions);
        Canvas c = new Canvas(new Texture(b));
        c.save();

        mPaint.setStyle(Paint.Style.STROKE_STYLE);//设置空心

        mPaint.setColor(new Color(Color.argb(255, 254, 219, 57)));

        if (intervalf < 1f) {
            RectFloat oval2 = new RectFloat(mWidth / 2 - mWidth / 3,
                    (float) ((float) (mHeight - mWidth / 6 - mWidth / 3)
                            + Math.sin(Math.toRadians(sun_angle)) * mWidth / 3),
                    mWidth / 2 + mWidth / 3,
                    (float) (mHeight - mWidth / 6 + mWidth / 3 + Math.sin(Math.toRadians(sun_angle)) * mWidth / 3));
            c.drawArc(oval2,
                    new Arc(180 + sun_angle, (180 - 2 * sun_angle) * intervalf, false),
                    mPaint);
        }

        mPaint.setStyle(Paint.Style.FILL_STYLE);//设置空心

        float y = (float) (Math.sin(Math.toRadians(sun_angle + (180 - 2 * sun_angle) * intervalf)) * mWidth / 3);
        float x = (float) (Math.cos(Math.toRadians(sun_angle + (180 - 2 * sun_angle) * intervalf)) * mWidth / 3);

        c.drawPixelMapHolder(new PixelMapHolder(getSun(intervalf)),
                mWidth / 2 - x - mWidth / 3 / 4,
                (float) (mHeight - mWidth / 6 - y - mWidth / 3 / 4 + Math.sin(Math.toRadians(sun_angle)) * mWidth / 3),
                mPaint);

        c.restore();

        return b;


    }


    private PixelMap getSun(float intervalf) {
        PixelMap.InitializationOptions initializationOptions = new PixelMap.InitializationOptions();
        initializationOptions.size = new Size(mWidth / 3 / 2, mWidth / 3 / 2);
        initializationOptions.pixelFormat = ARGB_8888;
        PixelMap b = PixelMap.create(initializationOptions);
        Canvas c = new Canvas(new Texture(b));
        c.save();
        mPaint.setStyle(Paint.Style.FILL_STYLE);//设置空心
        c.rotate(intervalf * 180, mWidth / 3 / 4, mWidth / 3 / 4);


        if (intervalf >= 0.3f || intervalf <= 0.7f) {
            mPaint.setColor(new Color(Color.argb(255, 254, 219, 57)));

        }
        if (intervalf < 0.3f) {

            float colorap = (float) (intervalf / 0.3f);
            int suncolor = (int) (230 + (25 * (colorap)));


            mPaint.setColor(new Color(Color.argb(suncolor, 254, 219, 57)));


        } else if (intervalf > 0.7f) {


            float colorap = (float) ((1f - intervalf) / 0.3f);
            int suncolor = (int) (230 + (25 * (colorap)));


            mPaint.setColor(new Color(Color.argb(suncolor, 254, 219, 57)));


        }


        if (intervalf > 0 && intervalf < 1) {
            c.drawCircle(mWidth / 3 / 4, mWidth / 3 / 4, mWidth / 3 / 10, mPaint);

            mPaint.setStrokeWidth(5);
            c.drawLine(new Point(mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5),
                            mWidth / 3 / 4),
                    new Point(mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5) - (mWidth / 3 / 10 / 2)
                            , mWidth / 3 / 4), mPaint


            );

            c.drawLine(new Point(mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5),
                            mWidth / 3 / 4),
                    new Point(mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)
                            , mWidth / 3 / 4), mPaint


            );


            c.drawLine(new Point(mWidth / 3 / 4, mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5))
                            , new Point(mWidth / 3 / 4,
                            mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5) - (mWidth / 3 / 10 / 2))
                    , mPaint


            );


            c.drawLine(new Point(mWidth / 3 / 4, mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)),
                    new Point(mWidth / 3 / 4,
                            mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)),
                    mPaint


            );


            c.drawLine(new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5))/ Math.sqrt(2))),
                            (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );


            c.drawLine(new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2))),
                            (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );


            c.drawLine(new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2))),
                    (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );

            c.drawLine(new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2))),
                    (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );


//            Log.e("eeeee", (Math.sqrt(2) + ""));


        } else if (intervalf == 0) {


            RectFloat oval1 = new RectFloat(mWidth / 3 / 4 - mWidth / 3 / 10, mWidth / 3 / 4 - mWidth / 3 / 10,
                    mWidth / 3 / 4 + mWidth / 3 / 10, mWidth / 3 / 4 + mWidth / 3 / 10);

            c.drawArc(oval1, new Arc(180, 180, true), mPaint);//小弧形

            mPaint.setStrokeWidth(5);


            c.drawLine(new Point(mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5),
                            mWidth / 3 / 4),
                    new Point(mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5) - (mWidth / 3 / 10 / 2)
                    , mWidth / 3 / 4), mPaint


            );

            c.drawLine(new Point(mWidth / 3 / 4, mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5))
                    , new Point(mWidth / 3 / 4,
                    mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5) - (mWidth / 3 / 10 / 2))
                    , mPaint


            );

            c.drawLine(new Point(mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5),
                    mWidth / 3 / 4),
                    new Point(mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)
                    , mWidth / 3 / 4), mPaint


            );


            c.drawLine(new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2))),
                    (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );

            c.drawLine(new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2))),
                    (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );


        } else if (intervalf == 1) {


            mPaint.setStrokeWidth(5);


            RectFloat oval1 = new RectFloat(mWidth / 3 / 4 - mWidth / 3 / 10, mWidth / 3 / 4 - mWidth / 3 / 10,
                    mWidth / 3 / 4 + mWidth / 3 / 10, mWidth / 3 / 4 + mWidth / 3 / 10);


            c.drawArc(oval1, new Arc(180, -180, true), mPaint);//小弧形


            c.drawLine(new Point(mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5),
                            mWidth / 3 / 4),
                    new Point(mWidth / 3 / 4 - mWidth / 3 / 10 - (mWidth / 3 / 10 / 5) - (mWidth / 3 / 10 / 2)
                    , mWidth / 3 / 4), mPaint


            );

            c.drawLine(new Point(mWidth / 3 / 4, mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5))
                    , new Point(mWidth / 3 / 4,
                    mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2))
                    , mPaint


            );

            c.drawLine(new Point(mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5),
                    mWidth / 3 / 4),
                    new Point(mWidth / 3 / 4 + mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)
                    , mWidth / 3 / 4), mPaint


            );


            c.drawLine(new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2))),
                    (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 - ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );

            c.drawLine(new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2))),
                    (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5)) / Math.sqrt(2)))),
                    new Point((float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2)))
                    , (float) (mWidth / 3 / 4 + ((float) (mWidth / 3 / 10 + (mWidth / 3 / 10 / 5) + (mWidth / 3 / 10 / 2)) / Math.sqrt(2))))
                    , mPaint


            );


        }
        c.restore();

        return b;
    }





    @Override
    public void onDraw(Component component, Canvas canvas) {
        canvas.save();
        canvas.drawLine(new Point(0 + mWidth / 12, mHeight - mWidth / 6)
                , new Point(mWidth - mWidth / 12, mHeight - mWidth / 6), mPaint);


        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mPaint.setTextSize(35);
        mPaint.setStrokeWidth(1);
        String startTime = getTimeText(SunstartTime);
        String endTime = getTimeText(SunendTime);
        int w = mPaint.getTextBounds(startTime).getWidth();
        int h = mPaint.getTextBounds(startTime).getHeight() * 2;
        canvas.drawText(mPaint,startTime, mWidth / 6 - w / 2, mHeight - mWidth / 6 + h);
        canvas.drawText(mPaint,endTime, mWidth - mWidth / 6 - w / 2, mHeight - mWidth / 6 + h);


        mPaint.setStyle(Paint.Style.STROKE_STYLE);//设置空心
        mPaint.setStrokeWidth(2.5f);
        mPaint.setPathEffect(new PathEffect(new float[]{14, 12}, 0));

        RectFloat oval1 = new RectFloat(mWidth / 2 - mWidth / 3,(float) ((float) (mHeight - mWidth / 6 - mWidth / 3)
                + Math.sin(Math.toRadians(sun_angle)) * mWidth / 3),
                mWidth / 2 + mWidth / 3,
                (float) (mHeight - mWidth / 6 + mWidth / 3 + Math.sin(Math.toRadians(sun_angle)) * mWidth / 3));
        canvas.drawArc(oval1, new Arc(180 + sun_angle, (180 - 2 * sun_angle), false), mPaint);

        float intervalf = 0f;
        try {
            long TodayInterval = getTimeInterval(SunstartTime, SunendTime);
            Timestamp ts = new Timestamp(System.currentTimeMillis());
            String nowtime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(ts.getTime());
            long nowInterval = getTimeInterval(SunstartTime, nowtime);
            intervalf = nowInterval * 1.0f / TodayInterval * mAnimatedValue;
            if (intervalf > 1f) {
                intervalf = 1f;
            }

        } catch (ParseException e) {
            e.printStackTrace();
        }

        canvas.drawPixelMapHolder(new PixelMapHolder(getSunbg(intervalf)), 0, 0, mPaint);
        canvas.restore();
    }

    @Override
    public boolean onEstimateSize(int i, int i1) {
        mHeight = EstimateSpec.getSize(i1);
        mWidth = EstimateSpec.getSize(i);
        return false;
    }

    private class HMEventHandler extends EventHandler {
        public HMEventHandler(EventRunner runner) throws IllegalArgumentException {
            super(runner);
        }

        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            int id = event.eventId;
            long param = event.param;
            if(param == 0){
                mAnimatedValue = 0f;
                invalidate();
            }else if(param == 1){
                start();
            }

        }
    }
}
